<template>
  <div>
    <el-dialog
      class="base-dialog"
      :custom-class="'panna-dialog_medium'"
      :title="title"
      :visible="dialogVisible"
      :append-to-body="true"
      destroy-on-close
      :before-close="handleClose"
    >
      <div class="dialog-content">
        <el-form ref="form" :model="form" :rules="rules" label-width="100px">
          <el-form-item label="控件标题" prop="label">
            <el-input v-model="form.label" @input="validateTitleLen"></el-input>
          </el-form-item>
          <el-form-item label="控件类型">
            <el-input v-model="typeText" disabled></el-input>
          </el-form-item>
          <!-- 图片控件排布类型 -->
          <el-form-item
            v-if="params.controlType === 'Image'"
            label="图片方向"
            style="width: 35%"
          >
            <el-select v-model="form.imgDirection" placeholder="请选择">
              <el-option
                v-for="item in directionList"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <!-- 下拉，复选，多选下拉 -->
          <el-form-item
            v-if="
              ['Checkbox', 'Radio', 'Select', 'MultipleSelect'].includes(
                params.controlType
              )
            "
            :label="multiLabel"
            prop="options"
          >
            <div class="custom-options">
              <div
                v-for="(item, index) in form.data"
                :key="item.id"
                class="custom-option-item"
              >
                <el-input
                  v-model="item.name"
                  @blur="validateRepeat(item)"
                ></el-input>
                <i
                  class="el-icon-plus option-add"
                  @mousedown="addOption(index)"
                ></i>
                <i
                  class="el-icon-minus option-del"
                  @mousedown="delOption(index)"
                ></i>
              </div>
            </div>
          </el-form-item>
          <!-- 小数位数 -->
          <el-form-item
            v-if="params.controlType === 'Number'"
            label="小数位数"
            prop="precision"
          >
            <el-input
              v-model="form.precision"
              @input="validateNumber($event, 'form.precision')"
            ></el-input>
          </el-form-item>
          <!-- 日期字段类型 -->
          <el-form-item
            v-if="params.controlType === 'DatePicker'"
            label="日期类型"
          >
            <el-select
              v-model="form.dateType"
              placeholder="请选择"
              @change="changeDate"
            >
              <el-option
                v-for="item in dateTypeList"
                :key="item.type"
                :label="item.label"
                :value="item.type"
              ></el-option>
            </el-select>
          </el-form-item>
          <!-- 必填非必填设置 -->
          <el-form-item v-if="params.controlType !== 'Table'" label="必填字段">
            <el-checkbox v-model="form.required"></el-checkbox>
          </el-form-item>
          <!-- 默认值 -->
          <el-form-item
            v-if="!['Table', 'Image'].includes(params.controlType)"
            label="默认值"
          >
            <!-- 选择类型控件 Array -->
            <div
              v-if="
                ['Checkbox', 'Radio', 'Select', 'MultipleSelect'].includes(
                  params.controlType
                )
              "
              class="control-edit-default select"
            >
              <el-select
                v-model="form.defaultValue"
                :multiple="
                  ['Checkbox', 'MultipleSelect'].includes(params.controlType)
                "
                placeholder="请选择"
                @change="changeSelectDefault"
              >
                <el-option
                  v-for="item in options"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                ></el-option>
              </el-select>
            </div>
            <!-- 日期类型控件 Object -->
            <div
              v-else-if="params.controlType === 'DatePicker'"
              class="control-edit-default"
            >
              <el-select
                v-model="form.defaultValue.type"
                @change="changeDateDefault"
              >
                <el-option
                  v-for="item in defaultDateOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                ></el-option>
              </el-select>
              <div
                v-show="form.defaultValue.type === 'customDate'"
                class="control-edit-default_custom"
              >
                <el-input
                  v-model.number="form.defaultValue.date"
                  type="text"
                  @input="validateNumber($event, 'customDate')"
                ></el-input>
                <span>天后</span>
              </div>
            </div>
            <!-- 需要输入的控件 String -->
            <div v-else class="control-edit-default input">
              <el-input v-model="form.defaultValue"></el-input>
            </div>
          </el-form-item>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="closeDialog('save')">保存</el-button>
        <el-button @click="closeDialog()">取消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { ELNControlMap } from "../../utils/dictionary.js";
export default {
  name: "UseControlEditDialog",
  props: {
    title: {
      type: String,
      default: "编辑字段属性",
    },
    dialogVisible: {
      type: Boolean,
      default: false,
    },
    params: {
      type: Object,
      default: () => {
        return {
          controlType: "text",
          label: "文本框",
        };
      },
    },
  },
  data() {
    const validOptions = (rule, value, callback) => {
      callback();
    };
    return {
      multiLabel: "",
      typeText: "",
      isDelClick: false,
      existSameData: false,
      dateTypeList: [
        {
          type: "Date",
          label: "日期",
        },
        {
          type: "Time",
          label: "时间",
        },
        {
          type: "DateTime",
          label: "日期和时间",
        },
      ],
      defaultDateOptions: [
        {
          id: "none",
          name: "无",
        },
        {
          id: "nowDate",
          name: "现在",
        },
        {
          id: "customDate",
          name: "自定义",
        },
      ],
      directionList: [
        {
          label: "横向（一页两张）",
          value: 0,
        },
        {
          label: "纵向（一页一张）",
          value: 1,
        },
      ],
      form: {
        id: "",
        label: "",
        controlType: "",
        precision: 0,
        required: false,
        defaultValue: "",
        data: [],
        dateType: "",
        imgDirection: 0,
      },
      rules: {
        label: [
          {
            required: true,
            message: "请输入控件标题",
            trigger: "blur",
          },
        ],
        options: [
          {
            required: true,
            message: "请输入选项内容",
            validator: validOptions,
          },
        ],
        precision: [
          {
            required: true,
            message: "请输入小数位数",
            trigger: "blur",
          },
        ],
      },
      date: undefined,
    };
  },
  computed: {
    options() {
      return this.form.data.filter((x) => x.name !== "");
    },
  },
  created() {
    for (var i in this.form) {
      Object.prototype.hasOwnProperty.call(this.params, i) &&
        (this.form[i] = this.params[i]);
    }
    this.typeText = ELNControlMap[this.form.controlType];
    this.multiLabel =
      this.params.controlType === "Checkbox" ? "复选框内容" : "下拉内容";
    ["Radio", "Checkbox", "Select", "MultipleSelect"].includes(
      this.form.controlType
    ) &&
      this.form.data.length === 0 &&
      (this.form.data = [this.createDefaultOption()]);
    if (this.params.controlType === "DatePicker" && !this.form.defaultValue) {
      this.form.defaultValue = {
        type: "none",
        date: "",
      };
    }
  },
  methods: {
    createDefaultOption() {
      return {
        id: new Date().getTime() + "",
        name: "",
        check: false,
      };
    },
    addOption(idx) {
      this.form.data.splice(idx + 1, 0, this.createDefaultOption());
    },
    delOption(idx) {
      this.isDelClick = true;
      this.form.data[idx].name === this.existSameData &&
        (this.existSameData = false);
      this.form.data.length === 1
        ? (this.form.data = [this.createDefaultOption()])
        : this.form.data.splice(idx, 1);
    },
    // 验证标题长度
    validateTitleLen(val) {
      const zhLen = val.match(/[\u4e00-\u9fa5]/g)?.length || 0;
      const otherLen = val.length - zhLen;
      const Len = this.params.controlType === "Table" ? 24 : 12;
      if (zhLen + otherLen / 2 > Len) {
        let newLabel = "";
        let count = 0;
        this.form.label.split("").forEach((x) => {
          count += x.match(/[\u4e00-\u9fa5]/g) ? 1 : 0.5;
          if (count > Len) return;
          newLabel += x;
        });
        this.form.label = newLabel;
        this.$message.warning("标题超出最大限制长度");
      }
    },
    // 验证添加的选项是否重复
    validateRepeat(item) {
      if (this.isDelClick) {
        this.isDelClick = false;
        return;
      }
      const isRepeat = this.form.data.some(
        (x) => x.name !== "" && x.name === item.name && x.id !== item.id
      );
      if (isRepeat) {
        event.target.focus();
        this.$message.warning(`选项${item.name}已存在`);
        this.existSameData = item.name;
        event.target.classList.add("repeat");
      } else {
        this.existSameData = false;
        event.target.classList.remove("repeat");
      }
    },
    changeDate(val) {
      this.form.defaultValue = {
        type: "none",
        date: "",
      };
    },
    changeDateDefault(val) {
      if (val !== "customDate") this.form.defaultValue.date = "";
    },
    changeSelectDefault(val) {
      this.form.data.forEach((x) => {
        x.check = ["Radio", "Select"].includes(this.form.controlType)
          ? val === x.id
          : val.includes(x.id);
      });
    },
    validateNumber(e, name) {
      name === "customDate"
        ? (this.form.defaultValue.date = e.replaceAll(/\D/g, ""))
        : (this.form.precision = Number(e.replaceAll(/\D/g, "")));
    },

    handleClose() {
      this.closeDialog();
    },
    closeDialog(type) {
      if (type !== "save") {
        this.$emit("update:dialogVisible", false);
        return;
      }
      // 判断选项是否重复
      if (this.existSameData) return;
      if (
        ["Checkbox", "Radio", "Select", "MultipleSelect"].includes(
          this.form.controlType
        ) &&
        !this.form.data.filter((x) => x.name !== "").length
      ) {
        this.$message.warning(`请保证${this.multiLabel}至少存在一个选项`);
        return;
      }
      this.$refs.form.validate((valid) => {
        if (!valid) return false;
        this.$emit("update:dialogVisible", false);
        // 日期转成符合标准的数据
        // 去除为null的选项
        this.form.data = this.form.data.filter((x) => x.text !== "");
        this.$emit("saveDialogConfig", this.form);
      });
    },
  },
};
</script>

<style lang="scss" scoped>
::v-deep .el-dialog__body {
  height: calc(100% - 54px - 64px);
  overflow: auto;
  .custom-options {
    .custom-option-item {
      display: flex;
      align-items: center;
      margin-bottom: 18px;

      &:last-child {
        margin-bottom: 0;
      }

      & > * {
        flex-shrink: 0;
      }

      & > .el-input {
        flex: 1;

        .el-input__inner.repeat:focus {
          border-color: red !important;
        }
      }

      & > .option-add,
      & > .option-del {
        width: 32px;
        height: 32px;
        line-height: 32px;
        text-align: center;

        &:hover {
          cursor: pointer;
          color: #0b64eb;
        }
      }
    }
  }

  .control-edit-default {
    display: flex;
    align-items: center;

    & > .control-edit-default_custom {
      display: flex;
      align-items: center;

      & > .el-input {
        flex-shrink: 0;
        width: 32px;
        margin: 0 20px;

        .el-input__inner {
          padding: 0;
          text-align: center;
        }
      }

      & > span {
        flex-shrink: 0;
      }
    }
  }

  .el-form-item.control-edit-delete > ::v-deep .el-form-item__content {
    margin-left: 0 !important;
    text-align: center;
  }

  .table-row-operate {
    margin-left: 20px;
  }
}

::v-deep .el-dialog__footer {
  text-align: center;
  padding: 16px !important;

  .el-button {
    width: 70px;
    & + .el-button {
      margin-left: 30px !important;
    }
  }
}
</style>
